#pragma once

#include "application/dispatcher/route_dispatcher.h"
#include "application/map/map_application_service.h"
#include "application/vehicle/vehicle_service.h"
#include <QObject>
#include <QHash>
#include <QList>
#include <memory>
#include <functional>

namespace application {
namespace dispatcher {

class DispatcherManager : public QObject {
    Q_OBJECT
public:
    explicit DispatcherManager(std::shared_ptr<vehicle::VehicleService> vehicleService,
                               std::shared_ptr<MapApplicationService> mapService,
                               std::shared_ptr<kernel::ILogger> logger,
                               QObject* parent = nullptr);
    ~DispatcherManager() override = default;

    void init();
    RouteDispatcher* getDispatcher(int floor) const;

    TaskPublishHandle stationTaskFromServer(const QString& station, int floor, const QString& operation = QString(), std::function<void()> cb = {});
    TaskPublishHandle stationTaskFromServer(int agvNumber, const QString& station, int floor, const QString& operation = QString(), std::function<void()> cb = {});
    void setDispatchCallback(std::function<void(int, const QList<QString>&)> cb);
    void setSolveFailureCallback(std::function<void(const QString&)> cb);
    void cancelPendingForAgv(int agvNumber);

private slots:
    void onFloorMapLoaded(int floor);

private:
    std::shared_ptr<vehicle::VehicleService> m_vehicleService;
    std::shared_ptr<MapApplicationService> m_mapService;
    std::shared_ptr<kernel::ILogger> m_logger;
    QHash<int, RouteDispatcher*> m_dispatchers; // floor -> dispatcher
    std::function<void(int, const QList<QString>&)> m_dispatchCallback;
    std::function<void(const QString&)> m_solveFailureCallback;
};

} // namespace dispatcher
} // namespace application
